<?php

include_once 'ZReader.php';
include_once 'ZMessageItem.php';

class ZMessageReader extends ZReader {
    /**
     * Get messages only in this thread id
     * @var Int
     */
    private $threadId = 0;

    /**
     * Generate command string
     * @return string
     */
    public function command() {
        return sprintf('messages %s %d %d %s %s %d %s %s %d %s'."\r\n",
            $this->session,
            $this->offset,
            $this->limit,
            $this->begin,
            $this->end,
            $this->timeZone,
            $this->languages,
            $this->types,
            $this->threadId,
            $this->query
        );
    }

    /**
     * Parse data that receive from server to object
     * @param $callback
     * @param $state
     * @return void
     */
    public function parse($callback, &$state) {
        $i          = 0;
        $count      = 0;
        $arr        = array();
        $succeed    = false;
        $total      = $this->readNum();

        //Read data while not end of file
        while (!$this->eof()) {
            //Read the first block is the length of the data
            $numBytes = $this->readNum();
            if ($numBytes >= 0 && $numBytes < 0xffffffff) {
                if ($i < 9){
                    $arr[] = $this->readStr($numBytes);
                }
                else{
                    $arr[] = $this->readNum($numBytes);
                }
                $i++;

                //Enough a item
                if ($i == 12) {
                    $item = new ZMessageItem($arr[0], $arr[1], $arr[2], $arr[3], $arr[4], $arr[5], $arr[6], $arr[7], $arr[8], $arr[9], $arr[10], $arr[11]);

                    $arr = array();
                    $i = 0;

                    if (is_callable($callback)) {
                        $callback($item, $total);
                    }
                    $count++;
                }
                //Not succeeded
                $succeed = false;
            }
            else if ($numBytes == 0xffffffff) {
                $succeed = true;
            }
        }

        $state = $succeed ? ($count > 0 ? 1 : 0) : -1;
    }

    /**
     * Filter the message only in this thread
     * This function must be call before read function
     * @param Int $threadId
     */
    public function filterByThread($threadId = 0) {
        $this->threadId = $threadId;
    }

    /**
     * @param null  $callback   callback function when receive data
     * @param int   $offset     started getting offset
     * @param int   $limit      item getting limitation
     * @return void
     * @throws Exception
     */
    public function read($callback = null, $offset = 0, $limit = 100) {
        parent::readData($callback, $offset, $limit);
    }
}

?>
